<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>故障波纹动效</title>
  <style>
    * { margin: 0; padding: 0;}
    body {
      background: #333;
      padding: 50px 30px;
    }
    .container {
      position: relative;
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      max-width: 1000px;
    }
    .item {
      width: 32%;
      margin-bottom: 30px;
    }
    .item img{
      display: block;
      width: 100%;
    }
    section {
      padding: 10px 25px;
      background-color: #fff;
    }
  </style>
  <style>
    .item img {
      filter: url(#noise)
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item"><img src="../轮播图/img/01.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/02.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/03.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/04.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/01.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/02.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/03.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/04.jpg" alt=""></div>
    <div class="item"><img src="../轮播图/img/01.jpg" alt=""></div>
  </div>
  <hr>
  <svg style="display: none;">
    <filter id="noise" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="linearRGB">
      <feTurbulence type="fractalNoise" baseFrequency="0 0.00001" numOctaves="2" seed="2" stitchTiles="stitch" x="0%" y="0%" width="100%" height="100%" result="turbulence1"/>
      <feDisplacementMap in="SourceGraphic" in2="turbulence1" scale="30" xChannelSelector="R" yChannelSelector="B" x="0%" y="0%" width="100%" height="100%" result="displacementMap1"/>
    </filter>
  </svg>
  <section >
    <p>可以应用与图片，文字，整个页面，也可以再鼠标移入时产生效果</p>
    <p>这里是使用 svg 的路径效果，可以参考链接：<a href="https://yoksel.github.io/svg-filters/#/">https://yoksel.github.io/svg-filters/#/</a></p>
    <ol>
      <li>这里使用到了svg-filters 里面的 feTurbulence （湍流滤镜）和 feDisplacementMap （置换滤镜）</li>
      <li>湍流滤镜：把内容变成一些噪点，置换滤镜：这里把噪点和图片结合起来</li>
      <li>
        <dl>
          <dt>简单解释 feTurbulence 和 feDisplacementMap</dt>
          <dt>feTurbulence</dt>
          <dd>type: turbulence （生成噪声更尖锐） 和 fractalNoise （生成噪声更柔和）</dd>
          <dd>baseFrequency：频率，代表一个点地方上噪声的剧烈程度，值越小，频率越低。两个参数一个是横向的，一个是纵向的</dd>
          <dt>feDisplacementMap</dt>
          <dd>scale  受滤镜影响的因素，值越大，影响越大</dd>
        </dl>
      </li>
      <li>将svg-filters 生成的代码复制到项目的svg去, svg 可以不用显示</li>
      <li>在图片的css 中使用滤镜：filter:url(svg>filter 的id)</li>
      <li>接下来是要改变 fractalNoise的 baseFrequency 纵向动画，从0.0001 到0.4 再到0.0001 ，如此反复</li>
      <li>引用 gsap</li>
      <li>设置时间线，gsap.timeline(), 通过to 方法设置运动信息</li>
      <li>通过 gsap.timeline 发生变化时触发onUpdate 回调，并把它变化的值保存到 feTurbulence 的 baseFrequency 中</li>
      <li>完成后先设置暂停时间线，然后判断图片是否加载完成后再执行</li>
    </ol>
  </section>
  <script src="https://cdn.bootcdn.net/ajax/libs/gsap/3.11.5/gsap.js"></script>
  <script>
    const tur = document.querySelector('feTurbulence')
    const tl = gsap.timeline({
      paused: true, // 动画不播放
      onUpdate: () => {
        // console.log(val.freq)
        tur.setAttribute('baseFrequency', `0 ${val.freq}`)
      }
    }); // 创建时间线
    //ps: 因为动画是通过时间线去运动的，不同的时间段有不同的表现

    const val = {
      freq: 0.00001
    }
    tl.to(val, {
      freq: 0.4,
      duration: 0.1 // 持续时间
    }) // 将纵向的变化从 0.00001  --> 0.4

    tl.to(val, {
      freq: 0.00001,
      duration: 0.1 
    }) // 将纵向的变化从 0.4 --> 0.00001 



    // 等待加载完成完成后执行动画
    const imgs = document.querySelectorAll('.container img');
    for(const img of imgs) {
      if (img.complete) {
        tl.play()
      } else {
        img.addEventListener('load', () => {
          tl.play()
        })
      }
  
    }
  </script>
</body>
</html>